package ro.pub.cs.hwchecker.login.client;

import ro.pub.cs.hwchecker.comm.client.data.LoginCredentials;
import ro.pub.cs.hwchecker.comm.client.json.JSONLoginRequestBuilder;
import ro.pub.cs.hwchecker.comm.client.req.CheckerCallback;
import ro.pub.cs.hwchecker.comm.client.req.CheckerRequest;
import ro.pub.cs.hwchecker.comm.client.req.CheckerRequestException;
import ro.pub.cs.hwchecker.comm.client.req.LoginRequestBuilder;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.DeckPanel;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HTMLTable;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

public class LoginDialog extends DialogBox implements ClickListener,
		CheckerCallback<Void>{
	private final VerticalPanel layoutPanel = new VerticalPanel();
	
	private final Button loginButton = new Button("Login");
	private final TextBox userTextBox = new TextBox();
	private final PasswordTextBox pwdTextBox = new PasswordTextBox();
	private final HTML helpText = new HTML();
	
	private final DeckPanel resultPanel = new DeckPanel();
	private final Image loadingImage = new Image("ajax-loader.gif");
	private final Label errorLabel = new Label("Error");
	
	public LoginDialog() {
		super(false, true);
		loginButton.addClickListener(this);
		
		// Set window title
		this.setText("Log into HWChecker");
		
		// Put user & pass labels and controls in a grid
		Grid g = new Grid(2, 2);
		HTMLTable.CellFormatter cf = g.getCellFormatter();
		
		g.setText(0, 0, "Username:");
		cf.setHorizontalAlignment(0, 0, HasHorizontalAlignment.ALIGN_RIGHT);
		g.setWidget(0, 1, userTextBox);
		
		g.setText(1, 0, "Password:");
		cf.setHorizontalAlignment(1, 0, HasHorizontalAlignment.ALIGN_RIGHT);
		g.setWidget(1, 1, pwdTextBox);
		
		layoutPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);
		layoutPanel.add(g);
		
		// Now add the login button
		layoutPanel.add(loginButton);
		
		// Prepare the results panel
		resultPanel.add(loadingImage);
		resultPanel.add(errorLabel);
		resultPanel.setWidth("100%");
		resultPanel.setVisible(false);
		
		
		layoutPanel.add(resultPanel);
	
		// Prepare the bottom text
		helpText.setHTML("<a href=\"mailto:support@cs.pub.ro\">Forgot password?</a>");
		layoutPanel.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT);
		layoutPanel.add(helpText);
		
		// Put it all in the dialog
		this.setWidget(layoutPanel);
	}

	public void onClick(Widget sender) {
		LoginRequestBuilder loginReq = new JSONLoginRequestBuilder();
		// Do not permit further requests
		loginButton.setEnabled(false);
		
		// Show visual progress
		resultPanel.showWidget(0);
		loadingImage.setSize(loadingImage.getWidth() + "px",
				loadingImage.getHeight() + "px");
		resultPanel.setVisible(true);
		
		try {
			loginReq.performLogin(new LoginCredentials(userTextBox.getText(),
					pwdTextBox.getText()), this);
		} catch (CheckerRequestException ex) {
			onCheckerError(null, ex);
		}
	}

	public void onCheckerError(CheckerRequest req, CheckerRequestException error) {
		errorLabel.setText("Authentication failed: " + error.getMessage());
		resultPanel.showWidget(1);
		
		loginButton.setEnabled(true);
	}

	public void onCheckerResponse(CheckerRequest req, Void v) {
		resultPanel.setVisible(false);
		Window.Location.replace(GWT.getHostPageBaseURL() + "app");
	}
}
